/**
 * 对象池属性需要实现的接口
 */
export interface IObjectItem{
    /**
     * 是否活跃
     */
    isActive : boolean,
    InitItem(...param: Array<any>) : void,
    CloseSelf() : void
}

/**
 * 对象池
 */
export class ObjectPool<T extends IObjectItem>{
    /**
     * 工厂函数
     */
    private factoryFunc : ()=> Promise<T>;
    /**
     * 池子本体
     */
    private pool : Array<T> = new Array();

    /**
     * 所有活跃的Item
     */
    public get Items() : Array<T> {
        let list = new Array();
        this.pool.forEach(element => {
            if(element.isActive){
                list.push(element);
            }
        });
        return list;
    }
    
    /**
     * 对象池构造函数
     * @param func item的工厂函数
     */
    constructor(func: () => Promise<T>) {
        this.factoryFunc = func;
        
    }

    /**
     * 从池子借出个体
     * @param param 
     * @returns 
     */
    public async LentItem(...param : Array<any>) : Promise<T>{
        let item : T = null;
        //  优先使用不活跃的池子个体
        for (const i of this.pool) {
            if(!i.isActive){
                item = i;
                break;
            }
        }
        if(!item){
            item = await this.factoryFunc();
        }
        item.InitItem(param);
        item.isActive = true;
        this.pool.push(item);
        return item;
    }
    
    /**
     * 归还个体
     * 被关闭的可以在LentItem中被覆盖
     * @param item 
     */
    public CloseItem(item : IObjectItem){
        item.CloseSelf();
    }

    public TestPoolCount(){
        console.log("pool length ="+this.pool.length);
    }


    public Clear()
    {
        for (const item of this.Items) {
            item.CloseSelf();
        }
    }

}